const { CheckIn, User } = require('../models');
const { Op } = require('sequelize');
const moment = require('moment');

// 今日打卡
const checkIn = async (req, res) => {
  try {
    const userId = req.user.id;
    const today = moment().format('YYYY-MM-DD');
    const { studyDuration, mood, summary, planTomorrow, completedTasks } = req.body;

    // 检查今日是否已打卡
    const existingCheckIn = await CheckIn.findOne({
      where: { user_id: userId, check_date: today }
    });

    if (existingCheckIn) {
      return res.status(400).json({ message: '今日已打卡，请勿重复打卡' });
    }

    // 创建打卡记录
    const checkInRecord = await CheckIn.create({
      user_id: userId,
      check_date: today,
      study_duration: studyDuration || 0,
      mood: mood || 'normal',
      summary: summary || '',
      plan_tomorrow: planTomorrow || '',
      completed_tasks: completedTasks || []
    });

    // 更新用户连续打卡天数
    await updateContinuousCheckinDays(userId);

    res.json({
      message: '打卡成功！',
      checkIn: checkInRecord
    });
  } catch (error) {
    console.error('打卡错误:', error);
    res.status(500).json({ message: '服务器内部错误' });
  }
};

// 获取打卡状态
const getCheckInStatus = async (req, res) => {
  try {
    const userId = req.user.id;
    const today = moment().format('YYYY-MM-DD');

    // 检查今日是否已打卡
    const todayCheckIn = await CheckIn.findOne({
      where: { user_id: userId, check_date: today }
    });

    // 获取连续打卡天数
    const user = await User.findByPk(userId, {
      attributes: ['continuous_checkin_days', 'total_study_days']
    });

    // 获取本月打卡记录
    const currentMonth = moment().format('YYYY-MM');
    const monthlyCheckIns = await CheckIn.findAll({
      where: {
        user_id: userId,
        check_date: {
          [Op.like]: `${currentMonth}%`
        }
      },
      order: [['check_date', 'ASC']]
    });

    res.json({
      hasCheckedToday: !!todayCheckIn,
      todayCheckIn,
      continuousCheckinDays: user.continuous_checkin_days,
      totalStudyDays: user.total_study_days,
      monthlyCheckIns: monthlyCheckIns.map(record => ({
        date: record.check_date,
        mood: record.mood,
        studyDuration: record.study_duration
      }))
    });
  } catch (error) {
    console.error('获取打卡状态错误:', error);
    res.status(500).json({ message: '服务器内部错误' });
  }
};

// 获取打卡历史
const getCheckInHistory = async (req, res) => {
  try {
    const userId = req.user.id;
    const { page = 1, limit = 10, month } = req.query;

    const whereCondition = { user_id: userId };
    
    if (month) {
      whereCondition.check_date = {
        [Op.like]: `${month}%`
      };
    }

    const { count, rows } = await CheckIn.findAndCountAll({
      where: whereCondition,
      order: [['check_date', 'DESC']],
      limit: parseInt(limit),
      offset: (parseInt(page) - 1) * parseInt(limit)
    });

    res.json({
      checkIns: rows,
      pagination: {
        total: count,
        page: parseInt(page),
        limit: parseInt(limit),
        totalPages: Math.ceil(count / parseInt(limit))
      }
    });
  } catch (error) {
    console.error('获取打卡历史错误:', error);
    res.status(500).json({ message: '服务器内部错误' });
  }
};

// 获取班级打卡排行榜
const getLeaderboard = async (req, res) => {
  try {
    const { period = 'week' } = req.query; // week, month, all

    let dateCondition = {};
    const now = moment();

    switch (period) {
      case 'week':
        const weekStart = now.clone().startOf('week');
        dateCondition = {
          check_date: {
            [Op.gte]: weekStart.format('YYYY-MM-DD')
          }
        };
        break;
      case 'month':
        const monthStart = now.clone().startOf('month');
        dateCondition = {
          check_date: {
            [Op.gte]: monthStart.format('YYYY-MM-DD')
          }
        };
        break;
      default:
        // 全部时间
        break;
    }

    // 获取用户打卡统计
    const users = await User.findAll({
      attributes: [
        'id', 
        'username', 
        'real_name', 
        'avatar', 
        'continuous_checkin_days',
        'total_study_days'
      ],
      include: [{
        model: CheckIn,
        as: 'checkIns',
        where: dateCondition,
        required: false,
        attributes: ['study_duration']
      }],
      order: [['continuous_checkin_days', 'DESC']]
    });

    const leaderboard = users.map(user => {
      const checkIns = user.checkIns || [];
      const totalStudyTime = checkIns.reduce((sum, checkIn) => sum + (checkIn.study_duration || 0), 0);
      
      return {
        id: user.id,
        username: user.username,
        realName: user.real_name,
        avatar: user.avatar,
        continuousCheckinDays: user.continuous_checkin_days,
        totalStudyDays: user.total_study_days,
        periodCheckInCount: checkIns.length,
        totalStudyTime
      };
    }).filter(user => user.periodCheckInCount > 0 || period === 'all');

    res.json({
      period,
      leaderboard: leaderboard.slice(0, 20) // 只返回前20名
    });
  } catch (error) {
    console.error('获取排行榜错误:', error);
    res.status(500).json({ message: '服务器内部错误' });
  }
};

// 更新打卡记录
const updateCheckIn = async (req, res) => {
  try {
    const { date } = req.params;
    const { studyDuration, mood, summary, planTomorrow, completedTasks } = req.body;
    const userId = req.user.id;

    const checkInRecord = await CheckIn.findOne({
      where: { user_id: userId, check_date: date }
    });

    if (!checkInRecord) {
      return res.status(404).json({ message: '打卡记录不存在' });
    }

    const updateData = {};
    if (studyDuration !== undefined) updateData.study_duration = studyDuration;
    if (mood !== undefined) updateData.mood = mood;
    if (summary !== undefined) updateData.summary = summary;
    if (planTomorrow !== undefined) updateData.plan_tomorrow = planTomorrow;
    if (completedTasks !== undefined) updateData.completed_tasks = completedTasks;

    await checkInRecord.update(updateData);

    res.json({
      message: '打卡记录更新成功',
      checkIn: checkInRecord
    });
  } catch (error) {
    console.error('更新打卡记录错误:', error);
    res.status(500).json({ message: '服务器内部错误' });
  }
};

// 计算并更新连续打卡天数
const updateContinuousCheckinDays = async (userId) => {
  try {
    const user = await User.findByPk(userId);
    if (!user) return;

    // 获取用户所有打卡记录，按日期倒序
    const checkIns = await CheckIn.findAll({
      where: { user_id: userId },
      order: [['check_date', 'DESC']],
      attributes: ['check_date']
    });

    if (checkIns.length === 0) {
      await user.update({ continuous_checkin_days: 0 });
      return;
    }

    let continuousDays = 1; // 至少有今天的打卡
    const today = moment();

    // 从今天开始往前检查连续性
    for (let i = 1; i < checkIns.length; i++) {
      const currentDate = moment(checkIns[i-1].check_date);
      const prevDate = moment(checkIns[i].check_date);
      
      // 如果相差正好1天，则连续
      if (currentDate.diff(prevDate, 'days') === 1) {
        continuousDays++;
      } else {
        break;
      }
    }

    await user.update({ continuous_checkin_days: continuousDays });
  } catch (error) {
    console.error('更新连续打卡天数错误:', error);
  }
};

module.exports = {
  checkIn,
  getCheckInStatus,
  getCheckInHistory,
  getLeaderboard,
  updateCheckIn
}; 